﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

using SBPweb.RIA.Shared.Contracts.Services;
using SBPweb.RIA.Server.Common.Communication;
using SBPweb.RIA.Server.Common.Hosting;

using SBPweb.PROvibe.Server.Library;

namespace SBPweb.PROvibe.Server.Library.Hosting
{

    public class CustomServiceHost<TService, TContract> : CustomHost
        where TService : IService
        where TContract : IService
    {

        #region Private fields

        private static HttpClientCredentialType authType;
        private string rootNamespace;

        #endregion

        #region Constructor logic

        static CustomServiceHost()
        {
            string auth = ConfigurationManager.AppSettings[Constants.AppSettingsKeys.ServiceHostAuthentication];
            if (string.IsNullOrEmpty(auth))
            {
                authType = HttpClientCredentialType.Windows;
            }
            else
            {
                authType = (HttpClientCredentialType)Enum.Parse(typeof(HttpClientCredentialType), auth);
            }
        }

        public CustomServiceHost(string pathOfSvc)
            : this(Constants.Services.DefaultNamespace, pathOfSvc)
        {
        }

        public CustomServiceHost(string rootNamespace, string pathOfSvc)
            : base(typeof(TService), typeof(TContract), pathOfSvc)
        {
            this.rootNamespace = rootNamespace;
            this.IsCustomFaultBehaviorActive = true;
            this.IsServiceDebugBehaviorActive = true;
        }

        #endregion

        #region Methods

        protected override Binding CreateBindingInstance(Type type, SiteBinding binding, Uri address)
        {
            BasicHttpBinding ret;
            ServiceMetadataBehavior smb = this.MetadataBehavior;
            switch (binding.Protocol)
            {
                default:
                    return base.CreateBindingInstance(type, binding, address);
                case "http":
                    ret = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
                    smb.HttpGetEnabled = true;
                    break;
                case "https":
                    ret = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    smb.HttpsGetEnabled = true;
                    break;
            }
            ret.MaxReceivedMessageSize = 10485760;
            ret.MaxBufferSize = 10485760;
            ret.MaxBufferPoolSize = 10485760;
            ret.Security.Transport.ClientCredentialType = authType;
            ret.Namespace = rootNamespace;
            ret.ReaderQuotas.MaxArrayLength = 10485760;
            return ret;
        }

        //protected override Binding CreateBindingInstanceForHttp(Type type, Uri address)
        //{
        //    BasicHttpBinding ret;
        //    switch (address.Scheme)
        //    {
        //        default:
        //        case "http":
        //            ret = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
        //            break;
        //        case "https":
        //            ret = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        //            break;
        //    }
        //    ret.MaxReceivedMessageSize = 10485760;
        //    ret.MaxBufferSize = 10485760;
        //    ret.MaxBufferPoolSize = 10485760;
        //    ret.Security.Transport.ClientCredentialType = authType;
        //    ret.Namespace = rootNamespace;
        //    ret.ReaderQuotas.MaxArrayLength = 10485760;
        //    return ret;
        //}

        //protected override Binding CreateBindingInstanceForTcp(Type type, Uri address)
        //{
        //    return base.CreateBindingInstanceForTcp(type, address);
        //}

        //protected override void CreateBindings()
        //{
        //    foreach (IISContextManager.SiteBinding binding in IISContextManager.GetBindings())
        //    {
        //        //try
        //        //{
        //        //string dnsSafeHost = ConfigurationManager.AppSettings[Constants.AppSettingsKeys.DnsSafeHost];
        //        //string scheme = "http";
        //        //if (!string.IsNullOrEmpty(dnsSafeHost))
        //        //{
        //        //    scheme = new Uri(dnsSafeHost).Scheme;
        //        //}
        //        Uri uri = 
        //        Binding httpBinding = CreateBindingInstanceForHttp(ContractType, uri);                
        //        dictBindings.Add(binding.Protocol, httpBinding);

        //        ServiceMetadataBehavior smb = this.MetadataBehavior;

        //        smb.HttpsGetEnabled = dictUrisByScheme.ContainsKey("https");
        //        smb.HttpGetEnabled = dictUrisByScheme.ContainsKey("http");

        //        #region REMOVED TCP Binding!
        //        dictUrisByScheme.Remove("net.tcp");
        //        //Binding tcpBinding = CreateBindingInstanceForTcp(ContractType, dictUrisByScheme["net.tcp"]);
        //        //if (tcpBinding != null)
        //        //{
        //        //    this.AddServiceEndpoint(
        //        //        ContractType,
        //        //        tcpBinding,
        //        //        dictUrisByScheme["net.tcp"]);
        //        //}

        //        //Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
        //        //if (dictUrisByScheme.ContainsKey("net.tcp"))
        //        //{
        //        //    this.AddServiceEndpoint(
        //        //        typeof(IMetadataExchange),
        //        //        mexBinding,
        //        //        string.Format("{0}/mex", dictUrisByScheme["net.tcp"]));
        //        //}
        //        #endregion
        //    }
        //}

        #endregion

    }

}